home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
games
/
litpz2gf.zoo
/
blckpuz1.lst
next >
Wrap
File List
|
1992-07-16
|
9KB
|
470 lines
' blckpuz1.gfa
' Block puzzle number 1 written in GFA Basic 3.5
' Seymour Shlien 14-July-1991
' 624 Courtenay Avenue
' Ottawa, Ontario
' Canada, K2A 3B5
' Public domain software
'
' Solution 1 to B
' Move pieces in following order
' 5,4,1,2,3,4 (up and right),1,6,7,8,9,5,4,1,6
' 7 (halfway),9,5,4,8,6,2,3,1.
'
' Solution 1 to C
' 5,4,1,2,3,4 (up and right) 1,6,7,8,9,5
' 4,1,6,7,8,9,5 (left and up),9,8,5,4,1
' 3,2,7,6,4 (up and left) 6
' 7,4,5,6,7,5 (right,up).
' 3,2,5,4,3,2 4(down and right),2,3,6,7,1
' 4,5,2,3,6,7,1,4(left,up),9,8,1
'
'
' Reference: Martin Gardner's "Sixth Book of Mathematical Games
' from Scientific American" W.H. Freeman and Company, San Francisco
' page 65
'
DIM block_x%(10),block_y%(10),block_w%(10),block_h%(10)
DIM board%(4,5)
DIM edge_status!(4)
DIM arrow_translation%(4)
DIM xbs_files$(30)
rez%=XBIOS(4)
IF rez%<>0
ALERT 3," Please switch to | low resolution! ",1,"Oops",b%
STOP
ENDIF
DEFMOUSE 0
DIM deskcolors%(16)
@get_deskcolors
x_scale%=20
y_scale%=20
board_w%=4
board_h%=5
@load_block_descriptor
@load_board
@load_mouse_poly
@dir_xbs_files
@read_sound
@dosound
VSETCOLOR 0,12,12,10
VSETCOLOR 3,10,14,0
VSETCOLOR 5,14,14,12
DEFFILL 0
PBOX 0,0,319,199
DEFFILL 1,1
@draw_entire_puzzle
LOCATE 19,3
PRINT "Hit space bar"
LOCATE 19,4
PRINT "to quit"
arrow_translation%(1)=4
arrow_translation%(2)=3
arrow_translation%(3)=1
arrow_translation%(4)=2
last_motion%=-1
FOR i%=1 TO 1000
block%=@pick_block
IF block%>0
motion%=@compute_edge_status(block%)
IF motion%>0
@execute_shift(block%,motion%)
last_motion%=motion%
ENDIF
ENDIF
' @print_board
PAUSE 20
NEXT i%
> PROCEDURE get_deskcolors
LOCAL i%
FOR i%=0 TO 15
deskcolors%(i%)=XBIOS(7,i%,-1)
NEXT i%
RETURN
> PROCEDURE restore_deskcolors
LOCAL i%
FOR i%=0 TO 15
SETCOLOR i%,deskcolors%(i%)
NEXT i%
RETURN
> PROCEDURE draw_block(number%)
LOCAL x%,y%
DEFFILL 3
x%=20+block_x%(number%)*x_scale%
y%=20+block_y%(number%)*y_scale%
PBOX x%,y%,x%+block_w%(number%)*x_scale%-3,y%+block_h%(number%)*y_scale%-3
GRAPHMODE 2
TEXT x%+2,y%+7,STR$(number%)
GRAPHMODE 1
RETURN
> PROCEDURE draw_entire_puzzle
LOCAL i%
DEFFILL 1
PBOX 19,19,21+board_w%*x_scale%,21+board_h%*y_scale%
FOR i%=1 TO numblk%
@draw_block(i%)
NEXT i%
TEXT 12,15,"A"
TEXT 20+board_w%*x_scale%,15,"B"
TEXT 12,30+board_h%*y_scale%,"C"
TEXT 20+board_w%*x_scale%,30+board_h%*y_scale%,"D"
'
TEXT 140,60,"Can you move block 1"
TEXT 140,70,"to corner B (easy) or"
TEXT 140,80,"corner C or D (harder)"
RETURN
> FUNCTION pick_block
LOCAL i%,j%
REPEAT
IF INKEY$<>""
@restore_deskcolors
END
ENDIF
UNTIL MOUSEK<>0
i%=(MOUSEX-20) DIV x_scale%
j%=(MOUSEY-20) DIV y_scale%
INC i%
INC j%
IF i%>=1 AND i%<=board_w%
IF j%>=1 AND j%<=board_h%
RETURN board%(i%,j%)
ENDIF
ENDIF
RETURN -1
ENDFUNC
> FUNCTION check_left_edge(n%)
' determines whether block n% can move left
LOCAL i%,x%,y%
x%=block_x%(n%)
y%=block_y%(n%)
IF x%<1
RETURN FALSE
ENDIF
FOR i%=1 TO block_h%(n%)
IF board%(x%,y%+i%)<>0
RETURN FALSE
ENDIF
NEXT i%
RETURN TRUE
ENDFUNC
> FUNCTION check_right_edge(n%)
LOCAL i%,x%,y%
x%=block_x%(n%)+block_w%(n%)+1
y%=block_y%(n%)
IF x%>board_w%
RETURN FALSE
ENDIF
FOR i%=1 TO block_h%(n%)
IF board%(x%,y%+i%)<>0
RETURN FALSE
ENDIF
NEXT i%
RETURN TRUE
ENDFUNC
> FUNCTION check_top_edge(n%)
LOCAL x%,y%,i%
x%=block_x%(n%)
y%=block_y%(n%)
IF y%<1
RETURN FALSE
ENDIF
FOR i%=1 TO block_w%(n%)
IF board%(x%+i%,y%)<>0
RETURN FALSE
ENDIF
NEXT i%
RETURN TRUE
ENDFUNC
> FUNCTION check_bottom_edge(n%)
LOCAL x%,y%,i%
x%=block_x%(n%)
y%=block_y%(n%)+block_h%(n%)+1
IF y%>board_h%
RETURN FALSE
ENDIF
FOR i%=1 TO block_w%(n%)
IF board%(x%+i%,y%)<>0
RETURN FALSE
ENDIF
NEXT i%
RETURN TRUE
ENDFUNC
> FUNCTION compute_edge_status(n%)
' The complicated part of this function is occurs when the
' block can move in either of two directions. The function
' then requests another mouse click indicating which direction.
LOCAL i%,sum%,sum2%
edge_status!(1)=@check_left_edge(n%)
edge_status!(2)=@check_right_edge(n%)
edge_status!(3)=@check_top_edge(n%)
edge_status!(4)=@check_bottom_edge(n%)
' verify unique direction
sum%=0
FOR i%=1 TO 4
IF edge_status!(i%)=TRUE
INC sum%
ENDIF
NEXT i%
rightmouse%=0
' only one direction to go
IF sum%=1
FOR i%=1 TO 4
IF edge_status!(i%)=TRUE
RETURN i%
ENDIF
NEXT i%
' two possible directions to go
ELSE IF sum%=2
PAUSE 20
DEFFILL 0
PBOX 130,50,319,120
DEFFILL 5
POLYFILL 6,mawse_x%(),mawse_y%() OFFSET 150,50
COLOR 1
POLYLINE 6,mawse_x%(),mawse_y%() OFFSET 150,50
COLOR 0
LINE 170,50,170,65
LINE 150,65,190,65
sum%=0
GRAPHMODE 2
' make rightmouse button to negate last move if possible
FOR i%=1 TO 4
IF edge_status!(i%)=TRUE
IF i%=1 AND last_motion%=2
rightmouse%=i%
ELSE IF i%=1
leftmouse%=i%
ENDIF
IF i%=2 AND last_motion%=1
rightmouse%=i%
ELSE IF i%=2
leftmouse%=i%
ENDIF
IF i%=3 AND last_motion%=4
rightmouse%=i%
ELSE IF i%=3
leftmouse%=i%
ENDIF
IF i%=4 AND last_motion%=3
rightmouse%=i%
ELSE IF i%=4
leftmouse%=i%
ENDIF
ENDIF
NEXT i%
' in some cases no motion is opposite to last_motion%
IF rightmouse%=0
FOR i%=1 TO 4
IF edge_status!(i%)=TRUE
INC sum%
IF sum%=1
TEXT 157,60,CHR$(arrow_translation%(i%))
ENDIF
IF sum%=2
TEXT 177,60,CHR$(arrow_translation%(i%))
ENDIF
ENDIF
NEXT i%
' rightmouse is set to opposite of last_motion%
ELSE
TEXT 157,60,CHR$(arrow_translation%(leftmouse%))
TEXT 177,60,CHR$(arrow_translation%(rightmouse%))
ENDIF
GRAPHMODE 1
TEXT 200,70,"Click left or"
TEXT 200,80,"right button"
' get next mouse click
REPEAT
UNTIL MOUSEK<>0
DEFFILL 0
PBOX 130,50,319,120
' for right mouse click return rightmouse% if defined
IF MOUSEK=2
IF rightmouse%=0
' search for second direction
sum%=0
FOR i%=1 TO 4
IF edge_status!(i%)=TRUE
INC sum%
ENDIF
IF sum%=2
RETURN i%
ENDIF
NEXT i%
ELSE
RETURN rightmouse%
ENDIF
ENDIF
IF rightmouse%=0
FOR i%=1 TO 4
IF edge_status!(i%)=TRUE
RETURN i%
ENDIF
NEXT i%
ELSE
RETURN leftmouse%
ENDIF
ENDIF
RETURN 0
ENDFUNC
> PROCEDURE update_board(n%,val%)
' sets the area occupied by block n% in board(*,*)
' to the value val%
LOCAL i%,j%,x%,y%
FOR j%=1 TO block_h%(n%)
y%=block_y%(n%)+j%
FOR i%=1 TO block_w%(n%)
x%=block_x%(n%)+i%
board%(x%,y%)=val%
NEXT i%
NEXT j%
RETURN
> PROCEDURE move_block(n%,dir%)
' dir% = 1,2,3,4 for left,right,up,down
SELECT dir%
CASE 1
DEC block_x%(n%)
CASE 2
INC block_x%(n%)
CASE 3
DEC block_y%(n%)
CASE 4
INC block_y%(n%)
ENDSELECT
' playtune if done
IF n%=1
IF block_x%(1)=2 AND block_y%(1)=0
@dosound
ELSE IF block_x%(1)=2 AND block_y%(1)=3
@dosound
ELSE IF block_x%(1)=0 AND block_y%(1)=3
@dosound
ENDIF
ENDIF
RETURN
> PROCEDURE execute_shift(n%,dir%)
update_board(n%,val%)
gradual_shift(n%,dir%)
move_block(n%,dir%)
update_board(n%,n%)
RETURN
> PROCEDURE gradual_shift(number%,dir%)
LOCAL x%,y%,i%,dist%,xl%,yl%
x%=20+block_x%(number%)*x_scale%
y%=20+block_y%(number%)*y_scale%
GET x%,y%,x%+block_w%(number%)*x_scale%-3,y%+block_h%(number%)*y_scale%-3,sec$
IF dir%>2
dist%=y_scale%
ELSE
dist%=x_scale%
ENDIF
COLOR 1
FOR i%=1 TO dist%
DEFFILL 3,1
VSYNC
SELECT dir%
CASE 1
xl%=x%+block_w%(number%)*x_scale%-3
LINE xl%,y%,xl%,y%+block_h%(number%)*y_scale%-3
DEC x%
PUT x%,y%,sec$
CASE 2
xl%=x%
LINE xl%,y%,xl%,y%+block_h%(number%)*y_scale%-3
INC x%
PUT x%,y%,sec$
CASE 3
yl%=y%+block_h%(number%)*y_scale%-3
LINE x%,yl%,x%+block_w%(number%)*x_scale%-3,yl%
DEC y%
PUT x%,y%,sec$
CASE 4
yl%=y%
LINE x%,yl%,x%+block_w%(number%)*x_scale%-3,yl%
INC y%
PUT x%,y%,sec$
ENDSELECT
NEXT i%
RETURN
> PROCEDURE print_board
LOCAL i%,j%
LOCATE 1,18
FOR j%=1 TO board_h%
FOR i%=1 TO board_w%
PRINT board%(i%,j%);" ";
NEXT i%
PRINT
NEXT j%
RETURN
> PROCEDURE dir_xbs_files
number_of_xbs_files%=0
~FSETDTA(BASEPAGE+128)
e%=FSFIRST("\XBS\*.XBS",-1)
DO UNTIL e%
xbs_files$(number_of_xbs_files%)=CHAR{BASEPAGE+158}
e%=FSNEXT()
INC number_of_xbs_files%
LOOP
RETURN
> PRO